package com.zh.work.service.platform.virtual.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zh.common.entity.Oauth;
import com.zh.work.dao.platform.agent.AgentInfoMapper;
import com.zh.work.dao.platform.branch.BranchInfoMapper;
import com.zh.work.dao.platform.merch.MerchInfoMapper;
import com.zh.work.dao.platform.virtual.VirtualCardMapper;
import com.zh.work.dao.platform.virtual.VirtualRechargeTransHMapper;
import com.zh.work.dao.platform.virtual.VirtualRechargeTransMapper;
import com.zh.work.entity.agent.AgentInfoEntity;
import com.zh.work.entity.branch.BranchInfoEntity;
import com.zh.work.entity.merch.MerchInfoEntity;
import com.zh.work.entity.virtual.VirtualCardEntity;
import com.zh.work.entity.virtual.VirtualRechargeTrans;
import com.zh.work.entity.virtual.VirtualRechargeTransH;
import com.zh.work.service.platform.virtual.VirtualRechargeTransService;
import com.zh.work.util.plateform.OfficeUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * code is far away from bug with the animal protecting
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 *
 * @Description: 账户充值信息设置业务逻辑实现层
 * @Author: Li.HuiNeng
 * @Create in: 2019/09/11
 * @Version: 1.0.1
 */
@Service
public class VirtualRechargeTransServiceImpl extends ServiceImpl<VirtualRechargeTransMapper, VirtualRechargeTrans> implements VirtualRechargeTransService {
    @Autowired
    private VirtualCardMapper cardMapper;

    @Autowired
    private BranchInfoMapper branchMapper;


    @Autowired
    private AgentInfoMapper agentMapper;

    @Autowired
    private MerchInfoMapper merchMapper;

    @Autowired
    private VirtualRechargeTransMapper rechargeTransMapper;

    @Autowired
    private VirtualRechargeTransHMapper rechargeTransHMapper;

    public static SimpleDateFormat TRACENO_DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");

    @Override
    public IPage<VirtualRechargeTrans> selectVirtualRechargeTransPages(Page<VirtualRechargeTrans> page, VirtualRechargeTrans param) {
        return this.rechargeTransMapper.selectPage(
                page,
                new QueryWrapper<VirtualRechargeTrans>().lambda()
                        .between(ObjectUtils.allNotNull(param.getStartDate(), param.getEndDate()),
                                VirtualRechargeTrans::getAddTime, param.getStartDate(), param.getEndDate())
                        .like(StringUtils.isNotEmpty(param.getMerchNo()), VirtualRechargeTrans::getMerchNo, param.getMerchNo())
                        .like(StringUtils.isNotEmpty(param.getMerchName()), VirtualRechargeTrans::getMerchName, param.getMerchName())
                        .like(StringUtils.isNotEmpty(param.getTraceNo()), VirtualRechargeTrans::getTraceNo, param.getTraceNo())
                        .like(StringUtils.isNotEmpty(param.getAgentNo()), VirtualRechargeTrans::getAgentNo, param.getAgentNo())
                        .like(StringUtils.isNotEmpty(param.getMerchNo()), VirtualRechargeTrans::getMerchNo, param.getMerchNo())  // 充值途径
                        .like(StringUtils.isNotEmpty(param.getCardNo()), VirtualRechargeTrans::getCardNo, param.getCardNo())
                        .like(StringUtils.isNotEmpty(param.getBankNo()), VirtualRechargeTrans::getBankNo, param.getBankNo())
                        .eq(StringUtils.isNotEmpty(param.getBranchNo()), VirtualRechargeTrans::getBranchNo, param.getBranchNo())
                        .eq(Objects.nonNull(param.getStatus()), VirtualRechargeTrans::getStatus, param.getStatus())
                        .eq(Objects.nonNull(param.getAmount()), VirtualRechargeTrans::getAmount, param.getAmount())
                        .eq(Objects.nonNull(param.getTransType()), VirtualRechargeTrans::getTransType, param.getTransType())
                        .last("and trans_type < 3")

        );
    }

    @Override
    public IPage<VirtualRechargeTransH> selectVirtualRechargeTransHPages(Page<VirtualRechargeTransH> page, VirtualRechargeTransH param) {
        return this.rechargeTransHMapper.selectPage(
                page,
                new QueryWrapper<VirtualRechargeTransH>().lambda()
                        .between(ObjectUtils.allNotNull(param.getStartDate(), param.getEndDate()),
                                VirtualRechargeTransH::getAddTime, param.getStartDate(), param.getEndDate())
                        .like(StringUtils.isNotEmpty(param.getMerchNo()), VirtualRechargeTransH::getMerchNo, param.getMerchNo())
                        .like(StringUtils.isNotEmpty(param.getMerchName()), VirtualRechargeTransH::getMerchName, param.getMerchName())
                        .like(StringUtils.isNotEmpty(param.getTraceNo()), VirtualRechargeTransH::getTraceNo, param.getTraceNo())
                        .like(StringUtils.isNotEmpty(param.getAgentNo()), VirtualRechargeTransH::getAgentNo, param.getAgentNo())
                        .like(StringUtils.isNotEmpty(param.getMerchNo()), VirtualRechargeTransH::getMerchNo, param.getMerchNo())  // 充值途径
                        .like(StringUtils.isNotEmpty(param.getCardNo()), VirtualRechargeTransH::getCardNo, param.getCardNo())
                        .like(StringUtils.isNotEmpty(param.getBankNo()), VirtualRechargeTransH::getBankNo, param.getBankNo())
                        .like(StringUtils.isNotEmpty(param.getLoginName()), VirtualRechargeTransH::getLoginName, param.getLoginName())
                        .eq(Objects.nonNull(param.getStatus()), VirtualRechargeTrans::getStatus, param.getStatus())
                        .eq(StringUtils.isNotEmpty(param.getBranchNo()), VirtualRechargeTransH::getBranchNo, param.getBranchNo())
                        .eq(Objects.nonNull(param.getTransType()), VirtualRechargeTransH::getTransType, param.getTransType())
                        .eq(Objects.nonNull(param.getAmount()), VirtualRechargeTransH::getAmount, param.getAmount())
                        .last("and trans_type < 3")
        );
    }

    @Override
    public int putModVirtualCardTrans(VirtualCardEntity virtualCardEntity) {
        return cardMapper.putModVirtualCardTrans(virtualCardEntity);
    }


    @Async
    @Override
    public Map<String, Object> putAddBatchVirtualRechargeTrans(MultipartFile file) throws Exception {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Oauth auth = (Oauth) authentication.getPrincipal();
        Map<String, Object> map = OfficeUtils.getVirtualCardListByMap(OfficeUtils.readExcelContent(file));
        StringBuffer sb = new StringBuffer();
        StringBuffer sb1 = new StringBuffer();
        AtomicInteger transNumSuccess = new AtomicInteger();
        AtomicInteger transNumError = new AtomicInteger();
        if (map.get("result") != null) {
            List<VirtualRechargeTrans> list = (List<VirtualRechargeTrans>) map.get("result");
            for (int i = 0; i < list.size(); i++) {
                // 查询指定商户下的账户信息
                List<VirtualCardEntity> listCard = cardMapper.selectList(new LambdaQueryWrapper<VirtualCardEntity>().eq(VirtualCardEntity::getMerchNo, list.get(i).getMerchNo()));
                if (listCard.size() > 0) {
                    // 存在账户，则修改金额，添加历史记录
                    int finalI = i;
                    listCard.forEach(f -> {
                        f.setAmount(list.get(finalI).getAmount());
                        int num = cardMapper.putModVirtualCardTrans(f);
                        if (num > 0) {
                            try {
                                // 查询机构信息
                                BranchInfoEntity branchInfoEntity = branchMapper.selectOne(new LambdaQueryWrapper<BranchInfoEntity>()
                                        .select(BranchInfoEntity::getBranchName)
                                        .eq(BranchInfoEntity::getBranchNo, f.getBranchNo()));
                                list.get(finalI).setBranchName(branchInfoEntity.getBranchName());
                                // 查询商户信息
                                MerchInfoEntity merch = merchMapper.selectOne(new LambdaQueryWrapper<MerchInfoEntity>().eq(MerchInfoEntity::getMerchNo, f.getMerchNo()));
                                if(merch!=null){
                                    list.get(finalI).setBranchNo(merch.getBranchNo());
                                    list.get(finalI).setBranchName(branchInfoEntity.getBranchName());
                                    list.get(finalI).setAgentNo(merch.getSuperAgent());
                                    // 查询代理商信息
                                    AgentInfoEntity agentBean = agentMapper.selectOne(new LambdaQueryWrapper<AgentInfoEntity>().eq(AgentInfoEntity::getAgentNo, merch.getSuperAgent()));
                                    if(agentBean == null){
                                        list.get(finalI).setAgentName(branchInfoEntity.getBranchName());
                                    }else{
                                        list.get(finalI).setAgentName(agentBean.getAgentName());
                                    }
                                    list.get(finalI).setMerchNo(merch.getMerchNo());
                                    list.get(finalI).setMerchName(merch.getMerchName());
                                }
                                list.get(finalI).setCardNo(f.getCardNo());
                                list.get(finalI).setTransType(1);
                                list.get(finalI).setStatus(2);
                                list.get(finalI).setTransAmount(list.get(finalI).getAmount());
                                list.get(finalI).setTransFee(0F);
                                list.get(finalI).setTraceNo("0000" + TRACENO_DATE_TIME_FORMAT.format(new Date()));
                                String transRefNo = TRACENO_DATE_TIME_FORMAT.format(new Date())+finalI;
                                list.get(finalI).setTransRefNo(transRefNo);
                                if (auth.getUserLoginName() != null) {
                                    list.get(finalI).setLoginName(auth.getUserLoginName());
                                } else {
                                    list.get(finalI).setLoginName("manager");
                                }
                                list.get(finalI).setTypeCode("0001");
                                Float amount = Float.valueOf(list.get(finalI).getAmount().toString());
                                list.get(finalI).setAmountBefore(f.getAvailAmount() - amount);
                                list.get(finalI).setAmountAfter(f.getAvailAmount());
                                list.get(finalI).insert();
                                transNumSuccess.incrementAndGet();
                            } catch (NumberFormatException e) {
                                log.error(e.getLocalizedMessage());
                            }
                        } else {
                            sb1.append(f.getCardNo() + ",");
                            transNumError.incrementAndGet();
                        }
                    });
                } else sb.append(listCard.get(i).getMerchNo() + ",");
            }
            StringBuffer stringBuffer = new StringBuffer();
            map.put("success", true);
            if (sb1.length() > 0) {
                stringBuffer.append(",账户为【" + (sb1.toString().length() - 1) + "]账户充值失败!");
            }
            if (sb.length() > 0) {
                stringBuffer.append("商户编号为[" + (sb.toString().length() - 1) + "]下不存在账户，请检查!");
            }
            if (stringBuffer.length() > 0) {
                map.put("msg", "充值成功笔数：" + transNumSuccess + "充值失败笔数：" + transNumError + stringBuffer.toString());
            }
        } else {
            map.put("excelErr", "导入Excel表格无效，请下载指定模板填写数据!");
        }
        return map;
    }
}
